home *** CD-ROM | disk | FTP | other *** search
/ Disc to the Future 2 / Disc to the Future Part II Programmer's Reference (Wayzata Technology)(6013)(1992).bin / MAC / THINKC / 4_0 / STANDALO / TOGSNDVO / TSV_SOUR / QUIK_FKE.C next >
C/C++ Source or Header  |  1991-02-11  |  14KB  |  686 lines

  1. /* Quik FKEY Installer.c
  2.     ⌐1991 by Mike Gleason Jr. */
  3.  
  4. #define NULL 0L
  5.  
  6. #define appleID                     400
  7.  
  8. #define fileID                        401
  9. #define     systemItem                1
  10. #define     suitcaseItem            2
  11. #define     quitItem                 4
  12.  
  13. #define editID                        402
  14.  
  15. #define SystemResFile    0
  16.  
  17. #define fkeyName    "\pTogSndVol FKEY"
  18. #define fkeyID    7
  19. #define infoW    400
  20. #define infoH    20
  21. #define infoM    10
  22.  
  23. #define DO_NOT_REPLACE_EXISTING_RESOURCE 99
  24.  
  25. #define SFSaveDisk        0x214        /* Negative of current volume refnum [WORD]    */
  26. #define CurDirStore        0x398        /* DirID of current directory [LONG]        */
  27. #define MBarHeight         0x0baa
  28.  
  29. /* MAC GLOBALS: */
  30.     MenuHandle        appleMenu, fileMenu, editMenu;
  31.     Rect            dragRect;
  32.     WindowPtr        InfoWindow;
  33.     Boolean            gHasWaitNextEvent;
  34.     SysEnvRec        gMac;
  35.     short            mbarheight;
  36.     Rect            WRect;
  37.  
  38. #pragma mark _protos
  39. void     main(void);
  40. void     InitMacintosh(void);
  41. void     InitVars(void);
  42. void     SetUpMenus(void);
  43. int     HandleEvent(void);
  44. void     HandleMouseDown(EventRecord *theEvent);
  45. void     HandleMenu (long mSelect);
  46. void    Message(char *str);
  47. char     *pStrcat(register char *s, register char *t);
  48. char     *pStrcpy(register char *s, register char *t);
  49. OSErr     SFGet(Str255 name, short *vref, long *dirid);
  50. int        SFPut(Str255 name);
  51. short    Install(int useSystemFile);
  52. OSErr    SFSystemDirectory(void);
  53. OSErr    SFDirID(int wd, int *volume, long *folder);
  54. short    CopyResource(short src, short dst, ResType type, 
  55.             short srcID, short dstID);
  56. void    DelayUntilEvent(void);
  57. void    MiniDoAbout(char *info);
  58.  
  59.  
  60. void main(void)
  61. {
  62.     InitMacintosh();
  63.     InitVars();
  64.     SetUpMenus();
  65.     for (;;)
  66.         HandleEvent();
  67. }
  68.  
  69.  
  70.  
  71.  
  72. void InitMacintosh(void)
  73. {
  74.     MaxApplZone();
  75.     
  76.     InitGraf(&thePort);
  77.     InitFonts();
  78.     FlushEvents(everyEvent, 0);
  79.     InitWindows();
  80.     InitMenus();
  81.     TEInit();
  82.     InitDialogs(0L);
  83.     InitCursor();
  84.     SysEnvirons(1, &gMac);
  85.     
  86. #define    WNETrapNum        0x60    /* Trap number of WaitNextEvent() */
  87. #define    UnImplTrapNum    0x9F    /* Trap number "unimplemented trap" */
  88.  
  89.     gHasWaitNextEvent =  NGetTrapAddress(WNETrapNum, ToolTrap) !=
  90.         NGetTrapAddress(UnImplTrapNum, ToolTrap);
  91. }
  92.  
  93.  
  94.  
  95.  
  96.  
  97. void InitVars(void)
  98. {
  99.     mbarheight = * (short *) MBarHeight;
  100.     InfoWindow = NULL;
  101.     dragRect = screenBits.bounds;
  102.     InsetRect(&dragRect,5,5);
  103. }
  104.  
  105.  
  106.  
  107.  
  108.  
  109. void SetUpMenus(void)
  110. {
  111.     /* Make and insert menus: */
  112.     
  113.     InsertMenu(appleMenu = NewMenu(appleID, "\p\024"), 0);
  114.         AppendMenu(appleMenu,"\pAbout Me╔;(-");
  115.         AddResMenu(appleMenu, 'DRVR');
  116.         
  117.     InsertMenu(fileMenu = NewMenu(fileID, "\pFile"), 0);
  118.         AppendMenu(fileMenu, "\pInstall in System File;Install in a ╥Suitcase╙;(-;Quit/Q");
  119.             
  120.     InsertMenu(editMenu = NewMenu(editID, "\pEdit"), 0);
  121.         AppendMenu(editMenu, "\pUndo/Z;(-;Cut/X;Copy/C;Paste/V;Clear/B");
  122.         
  123.     /* Check the initial items that need to be:  */        
  124.     /* CheckItem(whatMenu, whichItem, boolean);     */
  125.  
  126.     DrawMenuBar();    
  127. }
  128.  
  129.  
  130.  
  131.  
  132.  
  133.  
  134. int HandleEvent(void)
  135. {
  136.     int            ok;
  137.     EventRecord    theEvent;
  138.     char ch;
  139.     
  140.     if ( gHasWaitNextEvent ) {
  141.         ok = WaitNextEvent(everyEvent, &theEvent, 300, NULL);
  142.     }
  143.     else {
  144.         SystemTask();
  145.         ok = GetNextEvent(everyEvent, &theEvent);
  146.     }
  147.     
  148.     if (ok)
  149.       switch (theEvent.what)
  150.         {
  151.         case mouseDown:
  152.             HandleMouseDown(&theEvent);
  153.             break;
  154.             
  155.         case keyDown: 
  156.         case autoKey:
  157.             ch = (char) (theEvent.message & charCodeMask);
  158.             if ((theEvent.modifiers & cmdKey) != 0)
  159.                 HandleMenu(MenuKey(ch));
  160.             else
  161.             {
  162.                 /* TEKey... */
  163.             }
  164.             break;
  165.             
  166.         }
  167. }
  168. /* end HandleEvent */
  169.  
  170.  
  171.  
  172.  
  173.  
  174.  
  175. void HandleMouseDown(EventRecord *theEvent)
  176. {
  177.     WindowPtr    theWindow;
  178.     int            windowCode = FindWindow (theEvent->where, &theWindow);
  179.     
  180.     switch (windowCode)
  181.       {
  182.       case inSysWindow: 
  183.         SystemClick (theEvent, theWindow);
  184.         break;
  185.         
  186.       case inMenuBar:
  187.         HandleMenu(MenuSelect(theEvent->where));
  188.         break;
  189.       }
  190. }
  191. /* end HandleMouseDown */
  192.  
  193.  
  194.  
  195.  
  196.  
  197. void HandleMenu (long mSelect)
  198. {
  199.     int            menuID = HiWord(mSelect);
  200.     int            menuItem = LoWord(mSelect);
  201.     char        name[255];
  202.     GrafPtr        savePort;
  203.     WindowPeek    frontWindow;
  204.     
  205.     switch (menuID)
  206.       {
  207.       
  208.       case appleID:          
  209.         GetPort(&savePort);
  210.         GetItem(appleMenu, menuItem, name);
  211.         if (menuItem>1)
  212.             OpenDeskAcc(name);
  213.         else 
  214.         {
  215.             /* Do 'About' item */
  216.             MiniDoAbout("\pQuikRez Installer\r⌐1991 Mike Gleason Jr.");
  217.           }
  218.         SetPort(savePort);
  219.       break;
  220.       
  221.       case    fileID:
  222.         switch (menuItem)
  223.           {
  224.           case    systemItem:
  225.             Install(TRUE);
  226.             break;          
  227.             
  228.             case    suitcaseItem:
  229.                 Install(FALSE);
  230.                 break;
  231.                 
  232.           case    quitItem:
  233.             ExitToShell();
  234.             break;
  235.           }
  236.         break;
  237.                 
  238.     };    /* end of menu numbers  */
  239.     
  240.     HiliteMenu(0);
  241. }
  242.  
  243.  
  244.  
  245.  
  246. short    Install(int useSystemFile)
  247. {
  248.     OSErr        err;
  249.     Str255        fkeyRsrcName, destName, srcName, defVolname, str;
  250.     short        destResFile, srcResFile, oldResFile, vref, defVref;
  251.     short        srcID, destID, preferredDstID, numFKEYs;
  252.     long        dirid, defDirid;
  253.     register short i;
  254.     Handle        fkey;
  255.     ResType        type;
  256.     
  257.     SetRect(&WRect, infoM, mbarheight+infoM, 
  258.         infoM+infoW, mbarheight+infoM+infoH);
  259.     
  260.     oldResFile = CurResFile();
  261.     
  262.     InfoWindow = NewWindow
  263.         (
  264.             0L,                 /* window's storage ptr, 0L usually */
  265.             &WRect,                /* the window's rect */
  266.             "\pWindow Title",    /* the window's title */
  267.             FALSE,                /* is the window initially visible? */
  268.             dBoxProc,            /* type of window */
  269.             -1L,                /* front of which window, -1L = all */
  270.             0,                    /* has a go away box? */
  271.             0                    /* window refnum */
  272.         );
  273.     
  274.     if (!InfoWindow) goto barf;
  275.     SetPort(InfoWindow);
  276.     ShowWindow(InfoWindow);
  277.     SelectWindow(InfoWindow);
  278.     
  279.     
  280.     err = HGetVol((StringPtr)defVolname, &defVref, &defDirid);
  281.     
  282.     if (useSystemFile) destResFile = SystemResFile;
  283.     else
  284.     {
  285.         Message("\pSelect the file you want to install the FKEY in:");
  286.         if (SFSystemDirectory())    SysBeep(3L);
  287.         if (SFGet(destName, &vref, &dirid))
  288.         {
  289.             DisposeWindow(InfoWindow);
  290.             return (0);
  291.         }
  292.         destResFile = HOpenResFile(vref, dirid, destName, fsRdWrShPerm);
  293.         if (destResFile == -1 && ResError()) goto barf;
  294.     }
  295.  
  296.     err = HSetVol(defVolname, 0, defDirid);
  297.     
  298.     srcResFile = HOpenResFile(0, defDirid, fkeyName, fsRdPerm);
  299.     if (srcResFile == -1 && ResError())
  300.     {
  301.         /* our file wasn't in the defautlt directory. */
  302.         pStrcpy((char *) str, "\pPlease locate the file ╥");
  303.         pStrcat((char *) str, fkeyName);
  304.         pStrcat((char *) str, "\p.╙");
  305.         Message((char *) str);
  306.         * (short *)SFSaveDisk = -defVref;
  307.         * (long *)CurDirStore = defDirid;
  308.         if (SFGet(srcName, &vref, &dirid))
  309.         {
  310.             DisposeWindow(InfoWindow);
  311.             return (0);
  312.         }
  313.         srcResFile = HOpenResFile(vref, dirid, srcName, fsRdPerm);
  314.         if (srcResFile == -1 && ResError()) goto barf;
  315.     }
  316.     
  317.     UseResFile(srcResFile);
  318.     numFKEYs = Count1Resources('FKEY');
  319.     for (i=0; i<numFKEYs; i++)
  320.     {
  321.         UseResFile(srcResFile);
  322.         SetResLoad(FALSE);
  323.         type = 'FKEY';
  324.         fkey = Get1IndResource(type, i+1);
  325.         if (err = ResError()) continue;
  326.         SetResLoad(TRUE);
  327.         GetResInfo(fkey, &srcID, &type, fkeyRsrcName);
  328.         if (err = ResError()) continue;
  329.         {            
  330.             preferredDstID = srcID;
  331.             err = CopyResource(srcResFile, destResFile, type,
  332.                 srcID, preferredDstID);
  333.             if (err != noErr && err != DO_NOT_REPLACE_EXISTING_RESOURCE)
  334.                 goto puke;
  335.             else if (err == DO_NOT_REPLACE_EXISTING_RESOURCE)
  336.             {
  337.                 short i;
  338.                 
  339.                 for (i=5; i<=10; i++)
  340.                 {
  341.                     preferredDstID = i;
  342.                     if (i == 10) preferredDstID = 0;
  343.                     err = CopyResource(srcResFile, destResFile, type,
  344.                         srcID, preferredDstID);
  345.                     if (err != noErr && err != DO_NOT_REPLACE_EXISTING_RESOURCE)
  346.                         goto puke;
  347.                     else if (err == noErr) 
  348.                     {
  349.                         /* Hey! We found a slot for the fkey to fit. */
  350.                         /* Message */
  351.                         break; /* done, finally! */
  352.                     }    /* end if we installed in an alternate slot */
  353.                 }        /* end looping for empty slots */
  354.             }            /* end if our preferred slot was filled */
  355.         }                /* end if we can copy the fkey into the dest */
  356.         
  357.         if (err)
  358.             Message("\pSorry, there are already too many FKEYs in this file. <Click>");
  359.         else
  360.         {
  361.             char msg[256] = "\pInstalled ╥", tmp[8];
  362.             
  363.             if (*fkeyName < 1) pStrcat(msg, "\pUntitled");
  364.             else pStrcat(msg, (char *) fkeyRsrcName);
  365.             pStrcat(msg, "\p╙ okay. Type command-shift-");
  366.             NumToString((long)preferredDstID, tmp);
  367.             pStrcat(msg, tmp);
  368.             pStrcat(msg, "\p to run it. <Click>");
  369.             Message(msg);
  370.         }    /* end notifying the user of a successful install */
  371.         
  372.         InvertRect(&InfoWindow->portRect);
  373.         DelayUntilEvent();
  374.     }                    /* end looping, copying all fkeys to dest. */
  375.     
  376.     UseResFile(oldResFile);
  377.     if (srcResFile != SystemResFile) CloseResFile(srcResFile);
  378.     if (destResFile != SystemResFile) CloseResFile(destResFile);
  379.     DisposeWindow(InfoWindow);
  380.     return (1);
  381.     
  382. puke:
  383.     UseResFile(oldResFile);
  384.     if (srcResFile != SystemResFile) CloseResFile(srcResFile);
  385.     if (destResFile != SystemResFile) CloseResFile(destResFile);
  386.     Message("\pError occurred copying the FKEY.");
  387.     Delay(180, &dirid);
  388.  
  389. barf:
  390.     if (InfoWindow) DisposeWindow(InfoWindow);
  391.     SysBeep(3L);
  392.     return (0);
  393. }
  394.  
  395.  
  396.  
  397. short    CopyResource(short src, short dst, ResType type, 
  398.             short srcID, short dstID)
  399. {
  400.     Handle    RSRC = 0L;
  401.     short    oldResFile;
  402.     OSErr    err;
  403.     Str255    resname;
  404.     
  405.     oldResFile = CurResFile();
  406.     
  407.     UseResFile(dst);
  408.     RSRC = Get1Resource(type, dstID);
  409.                             /*    see if we have a resource with
  410.                                 the same id already present. */
  411.     err = ResError();
  412.     if (!err && RSRC)
  413.     {
  414.         ReleaseResource(RSRC);
  415.         return (DO_NOT_REPLACE_EXISTING_RESOURCE);
  416.     }
  417.     
  418.     UseResFile(src);
  419.     
  420.     RSRC = Get1Resource(type, srcID);
  421.                             /* load the source rsrc */
  422.     if (err = ResError()) goto heave;
  423.     
  424.     GetResInfo(RSRC, &srcID, &type, resname);
  425.                             /*    we need to do this to get the 
  426.                                 resource's name, if any */
  427.     if (err = ResError()) goto heave;
  428.     
  429.     UseResFile(dst);
  430.     
  431.     DetachResource(RSRC);    /*    have to detach it to make a copy */
  432.     AddResource(RSRC, type, dstID, resname);
  433.                             /*    now actually copy it */
  434.     if (err = ResError()) goto heave;
  435.         
  436.     ChangedResource(RSRC);    /*    mark it as changed */
  437.     if (err = ResError()) goto heave;
  438.     
  439.     UpdateResFile(dst);        /*    write out the resource file */
  440.     err = ResError();
  441.     
  442.     ReleaseResource(RSRC);    /*    we don't need it any more */
  443. heave:
  444.     UseResFile(oldResFile);
  445.     return (err);
  446. }    /* CopyResource */
  447.  
  448.  
  449.  
  450.  
  451. void    Message(char *str)
  452. {
  453.     if (!InfoWindow) return;
  454.     SetPort(InfoWindow);
  455.     EraseRect(&InfoWindow->portRect);
  456.     TextFont(geneva);
  457.     TextSize(9);
  458.     MoveTo(10, 13);
  459.     DrawString(str);
  460.     ValidRect(&InfoWindow->portRect);
  461. }
  462.  
  463.  
  464.  
  465.  
  466. char *pStrcat(register char *s, register char *t)
  467. {
  468.     register char *s2;
  469.     register short tLen;
  470.  
  471.     s2 = s + *s;
  472.     *s += (tLen = *t);
  473.     for (++tLen; --tLen; s2[tLen] = t[tLen]);
  474.     return (char *) (s);
  475. }
  476.  
  477.  
  478.  
  479.  
  480.  
  481. char *pStrcpy(register char *s, register char *t)
  482. {
  483.     register short    tLen;
  484.  
  485.     for (tLen = *t + 1; tLen--; s[tLen] = t[tLen]);
  486.     return (char *) (s);
  487. }
  488.  
  489.  
  490.  
  491.  
  492.  
  493. OSErr     SFGet(Str255 name, short *vref, long *dirid)
  494. {
  495.     SFReply        reply;
  496.     SFTypeList    typeList;
  497.     Point        location = {0x40,0x40};
  498.     OSErr        err;
  499.     
  500.     location.v = mbarheight + infoH + (3*infoM);
  501.     
  502.     SFGetFile(location,                /* location */
  503.         "\pSpace for Rent",            /* vestigial string */
  504.         NULL,                        /* fileFilter */
  505.         -1,                            /* numtypes; -1 means all */
  506.         &typeList,                    /* array to types to show */
  507.         NULL,                        /* dlgHook */
  508.         &reply);                    /* record for returned values */
  509.  
  510.     
  511.     if (reply.good)
  512.     {
  513.         pStrcpy((char *) name, (char *) reply.fName);
  514.         if (err = SetVol(name, reply.vRefNum)) return (err);
  515.         if (err = SFDirID(reply.vRefNum, vref, dirid)) return (err);
  516.         return (noErr);
  517.     }
  518.     else
  519.         return (1);    /* nothing selected */
  520. };
  521.  
  522.  
  523.  
  524.  
  525.  
  526. int         SFPut(Str255 name)
  527. {
  528.     SFReply     reply;
  529.     Point        location = {0x40,0x40};
  530.     OSErr        err;
  531.     
  532.     SFPutFile(location,                /* location */
  533.         "\pSave document as:",        /* prompt string */
  534.         name,                        /* original name */
  535.         NULL,                        /* dlgHook */
  536.         &reply);                    /* record for returned values */
  537.  
  538.     if (reply.good)
  539.     {
  540.         pStrcpy((char *) name, (char *) reply.fName);
  541.         err = SetVol(name, reply.vRefNum);
  542.         return ((err == noErr));
  543.     }
  544.     else
  545.         return (FALSE);
  546. };
  547.  
  548.  
  549.  
  550.  
  551.  
  552. OSErr    SFSystemDirectory(void)
  553. {
  554.     WDPBRec            pb;
  555.     SysEnvRec        theWorld;
  556.     Str255            name;
  557.     OSErr            err;
  558. #ifndef SFSaveDisk
  559. #define SFSaveDisk        0x214        /* Negative of current volume refnum [WORD]    */
  560. #define CurDirStore        0x398        /* DirID of current directory [LONG]        */
  561. #endif
  562.     if (err = SysEnvirons(1, &theWorld))
  563.         return (err);
  564.  
  565.     pb.ioNamePtr = (StringPtr) name;
  566.     pb.ioCompletion = 0L;
  567.     pb.ioVRefNum = theWorld.sysVRefNum;
  568.     pb.ioWDIndex = 0;
  569.     pb.ioWDProcID = 0;
  570.     pb.ioWDVRefNum = 0;
  571.     if ((err = PBGetWDInfo(&pb,false)))
  572.         return (err);
  573.  
  574.     *(long *)CurDirStore = pb.ioWDDirID;
  575.     *(short *)SFSaveDisk = -pb.ioWDVRefNum;
  576.         /* on the next SFGetFile (╔) it will open in the System Folder. */
  577.         
  578.     return (noErr);
  579. }    /* SFSystemDirectory */
  580.  
  581.  
  582.  
  583.  
  584.  
  585.  
  586. OSErr    SFDirID(int wd, int *volume, long *folder)
  587. {
  588.     WDPBRec pb;
  589.     char name[72];
  590.     OSErr    err;
  591.     
  592.     pb.ioNamePtr = (StringPtr)name;
  593.     pb.ioVRefNum = wd;
  594.     pb.ioWDIndex = 0;
  595.     pb.ioWDProcID = 0;
  596.     pb.ioWDVRefNum = 0;
  597.     err = PBGetWDInfo(&pb, false);
  598.     if (err) return (err);
  599.     *volume = pb.ioWDVRefNum;
  600.     *folder = pb.ioWDDirID;
  601.     return (noErr);
  602. }    /* SFDirID */
  603.  
  604.  
  605.  
  606.  
  607.  
  608.  
  609. void    DelayUntilEvent(void)
  610. {
  611.     EventRecord E;
  612.     int    quikMask = keyDownMask + autoKeyMask + mDownMask;
  613.     
  614.     /*    delay until the mouse button is pressed, or a key is pressed */
  615.     /*    ...and multifinder friendly, too! */
  616.             
  617.     while (1)
  618.     {
  619.         if (GetNextEvent(quikMask, &E))
  620.             break;
  621.         SystemTask();
  622.     }
  623. }
  624.  
  625.  
  626.  
  627.  
  628.  
  629.  
  630.  
  631. void    MiniDoAbout(char *info)
  632. {
  633.     WindowPtr     AboutWindow;
  634.     Rect         ARect = {0, 0, 64, 256};
  635.     GrafPtr        oldPort;
  636.     EventRecord E;
  637.     int            quikMask = keyDownMask + autoKeyMask + mDownMask;
  638.     int            width, height;
  639.     
  640.     GetPort(&oldPort);
  641.     
  642.     /* Center the rectangle on the screen */
  643.     
  644.     height = (ARect.bottom - ARect.top);
  645.     width =     (ARect.right  - ARect.left);
  646.     ARect.left = (screenBits.bounds.right - width) / 2;
  647.     ARect.right = ARect.left + width;
  648.     ARect.top = (screenBits.bounds.bottom - height) / 3;  /* Apple's╔ */
  649.     ARect.bottom = ARect.top + height;
  650.     
  651.     AboutWindow = NewWindow
  652.     (
  653.         0L,                 /* window's storage ptr, 0L usually */
  654.         &ARect,                /* the window's rect */
  655.         "\pWindow Title",    /* the window's title */
  656.         0,                    /* is the window initially visible? */
  657.         altDBoxProc,            /* type of window */
  658.         -1L,                /* front of which window, -1L = all */
  659.         0,                    /* has a go away box? */
  660.         0                    /* window refnum */
  661.     );
  662.     
  663.     if (!AboutWindow) return;
  664.         
  665.     ShowWindow(AboutWindow); 
  666.     SetPort(AboutWindow);
  667.     SelectWindow(AboutWindow);    
  668.     ARect = AboutWindow->portRect;
  669.     EraseRect(&ARect);
  670.     
  671.     InsetRect(&ARect, 10, 10);
  672.     TextFont(0);
  673.     TextSize(12);
  674.     TextFace(italic);
  675.     TextBox(info+1, (long) *info, &ARect, teJustLeft);
  676.     
  677.     while (1)
  678.     {
  679.         if (GetNextEvent(quikMask, &E))
  680.             break;
  681.         SystemTask();
  682.     }
  683.     DisposeWindow(AboutWindow);
  684.     SetPort(oldPort);
  685. }    /* MiniDoAbout */
  686.